#include "IndexParser.h"

#include "IndexTable.h"
#include <fstream>
#include <cstring>
#include <iostream>
#include <map>

using namespace std;

map<string,string> IndexParser::mapaConv;

IndexParser::IndexParser()
{
}

IndexParser::~IndexParser()
{
}

void IndexParser::fillConvMap()
{
	/**
	 * Loading hash for HTML Special Codes translation
	 */
		ifstream convFile;
		convFile.open("/work/util/ConvTable.txt", ios::in);
		string before;
		string after;
		while(!convFile.eof())
		{
			convFile >> before;
			convFile >> after;
			mapaConv[before]=after;
			 cout << "before: " << before << " e after: " << after << endl;
		}
		convFile.close();
}

void IndexParser::getTextFromPage(string filename,string fileID)
{


	ifstream file;
	ofstream out;
	out.open("/work/abstract00.rsm", ios::out | ios::app);
	bool shallPrint=true;
	int insideScript=0;
	int insideStyle=0;
	file.open(filename.c_str(),ios::in);
	string line;
	getline (file,line);
	out << fileID << " " << line << endl;
	int scriptsNested=0;
	int stylesNested=0;
	string scrCnt;
	while(!file.eof())
	{
		getline(file,line);
		//cout << "Li linha: " << line << endl;
		scrCnt = line;
		shallPrint = true;
		//cout << "Started Treating scripts and styles" << endl;
		//cout << " Para a linha: " << line << endl;
		while(scrCnt.find("<script") != string::npos)
		{
			int posSrc = scrCnt.find("<script");
			int posNextGT = scrCnt.find(">", posSrc);
			int posNextClosing = scrCnt.find("/>", posSrc);
			line="";
			//cout << "Tratando os %<script% para: " << scrCnt << endl;
			if(scrCnt.size()- posSrc - 7 >= 0)
				scrCnt = scrCnt.substr(0,posSrc).append(scrCnt.substr(posSrc+7,scrCnt.size()-posSrc-6));
			else
				scrCnt = scrCnt.substr(0,posSrc);
			//cout << "Resultado: " << scrCnt << endl;
			if((posNextClosing==string::npos) || posNextClosing > posNextGT )
				scriptsNested++;
		}
		while(scrCnt.find("/script>") != string::npos)
		{
			int posSrc = scrCnt.find("/script>");
			//cout << "Tratando os %/script>% para: " << scrCnt << endl;
			if(scrCnt.size()- posSrc - 8 >= 0)
				scrCnt = scrCnt.substr(posSrc+8,scrCnt.size()-posSrc-7);
			else 
				scrCnt = "";
			//cout << "Resultado: " << scrCnt << endl;
			line="";
			scriptsNested--;
		}
		while(scrCnt.find("<style") != string::npos)
		{
			int posSrc = scrCnt.find("<style");
			int posNextGT = scrCnt.find(">", posSrc);
			int posNextClosing = scrCnt.find("/>", posSrc);
			line="";
			//cout << "Tratando os %<style% para: " << scrCnt << endl;
			if(scrCnt.size()- posSrc - 6 >= 0)
							scrCnt = scrCnt.substr(0,posSrc).append(scrCnt.substr(posSrc+6,scrCnt.size()-posSrc-5));
						else
							scrCnt = scrCnt.substr(0,posSrc);
			//cout << "Resultado: " << scrCnt << endl;
			if((posNextClosing==string::npos) || posNextClosing > posNextGT )
				stylesNested++;
		}
		while(scrCnt.find("/style>") != string::npos)
		{
			int posSrc = scrCnt.find("/style>");
			//cout << "Tratando os %/style% para: " << scrCnt << endl;
			if(scrCnt.size()- posSrc - 7 >= 0)
				scrCnt = scrCnt.substr(posSrc+7,scrCnt.size()-posSrc-6);
			else 
				scrCnt = "";
			//cout << "Resultado: " << scrCnt << endl;
			line="";
			stylesNested--;
		}
		if(scriptsNested > 0 || stylesNested >0)
			line="";
		
		//cout << "Finished Treating scripts and styles" << endl;
			
		if(!shallPrint)
		{
			if(line.find(">") != string::npos)
			{
				line = line.erase(0,line.find(">"));
				shallPrint = true;
			}
			else
				line = line.erase(0);
		}
		 //cout << "Started treating <" << endl;
		while(line.find("<") != string::npos)
		{
			//cout << "Looking for < in:  " << line << endl;
			if(line.find(">") > line.find("<") && line.find(">")!=string::npos)
			{
				line = line.erase(line.find("<"),line.find(">")-line.find("<")+1);
				shallPrint = true;
			}
			else
			{
				line = line.substr(0,line.find("<"));
				shallPrint = false;
			}
		}
		//cout << "Stoped looking for < in:  " << line << endl;
		while(line.find_first_of(" \t\n\b\r\f\a\0") == 0)
			line = line.substr(1);
		while(line.find("\t") == 0)
			line = line.substr(1);
		
		//cout << "Linha esta como: " << line << endl;
		 //cout << "Started trating special codes" << endl;
		if(line.size() >0 && line != "")
		{
			while(line.find("&") != string::npos)
			{
				int epos = line.find("&");
				int nextSC = line.find(";",epos);
				if((nextSC - epos) > 8 || nextSC == string::npos )
				{
					line = line.substr(0,epos).append("e").append(line.substr(epos+1,line.size()-epos+1));
				}
				else
				{
					string block = line.substr(epos, nextSC-epos);
					if(mapaConv.find(block) != mapaConv.end())
						line.replace(epos,nextSC-epos, mapaConv[block]);
					else
					{
						line.replace(epos,nextSC-epos, " ");
					}
				}
			}
			out << line << endl;
			//cout << line << endl;
		}
	} 
	out << "&@_" << endl;
	file.close();
	out.close();
}

void IndexParser::getWordsFromText(ifstream *file,IndexTable* index)
{
	if(file->is_open())
	{
		string doc;
		ofstream out;
		out.open("C:\\getIndexTableSize.txt", ios::out);
		
		while(!file->eof())
		{
			*file >> doc;
			out << "Doc : " << doc << " ";
			//Pula linha
			string line;
			getline(*file,line);
			out << "Page : " << line << endl;
			getWordsFromPage(file,index,doc);
		}
	}
}

void IndexParser::getWordsFromPage(ifstream* file, IndexTable* index, string doc)
{
	string word;
	
	ofstream out,trash;
	out.open("C:\\Words.txt", ios::out);
	trash.open("C:\\Trash.txt", ios::out);
	int pos =1;
	
	while(word.compare("&@_")!= 0 && !file->eof())	//Enquanto nao termina a pagina
	{		
		*file >> word;
			
		if(ehPalavra(&word))
		{
			out << word << endl;
			//wordCounter->addWordCounter(ToLower(&word),doc);
			index->InserirWord(ToLower(&word),doc,pos);
			pos++;
		}
		else
		{
			trash << word << endl;
		}		
	}
	cout << "Fim de Pagina" << endl;
}

// Primeira Passagem - Contar o numero de ocorrencias de uma palvra

void IndexParser::getIndexTableSize(ifstream* file, WordCounterTable* wordCounter)
{
	if(file->is_open())
	{
		string doc;
		ofstream out;
		out.open("/work/getIndexTableSize.txt", ios::out);
		
		while(!file->eof())
		{
			*file >> doc;
			string url;
			*file >> url;
//			//Pula linha
//			string line;
//			getline(*file,line);
			out << doc << " ";
			out << url << endl;
			countWordsFromPage(file,wordCounter,doc);
		}
	}
}


void IndexParser::countWordsFromPage(std::ifstream *file,WordCounterTable* wordCounter, string doc)
{
	string word;
	
	ofstream out;
	out.open("/work/countWordsFromPage.txt", ios::app);
	/*TODO:
	 * verificar este loop
	 */
	
	while(word.compare("&@_")!= 0 && !file->eof())	//Enquanto nao termina a pagina
	{		
		*file >> word;
		cout << word << endl;
			
		if(ehPalavra(&word))
		{
			out << word << endl;
			wordCounter->addWordCounter(ToLower(&word),doc);				
		}
		else
		{
			//out << word << endl;
			//out <<  word << endl;
		}		
	}
	cout << "Fim de Pagina" << endl;
}

bool IndexParser::ehPalavra(string * word)
{
	//Simbolos que uma palavra NAO deve conter
	if(word->find_first_of("@#$%&*+=<>\\/") != string::npos)
		return false;
	
	size_t separador;
	
	//Reticencias - devem ser tratados antes do Separador
	// ex: word...
	separador = word->find("...");
	if(separador != string::npos)
	{	
		if(separador == word->size()-3)
		{
			cout << "Found " << word->at(word->size()-1) << " from word " << word << endl;
			word->erase(separador);
		}
		else
			return false;
	}
	// Aspas, Parentesis,
	//ex "Word
	
	separador = word->find_first_of("\"'([{");
	if(separador != string::npos)
	{	
		if(separador == 0)
			word->erase(separador);
		else
			return false;
	}	
		
	// Separadores no fim da palavra
	// ex: word,
	separador = word->find_first_of(".,;:!?)}] \t\n\b\r\f");
	if(separador != string::npos)
	{	
		if(separador == word->size()-1)
		{
			//cout << "Found " << word.at(word.size()-1) << " from word " << word << endl;
			word->erase(separador);
		}
		else if(separador == 0)
		{
			//cout << "Found " << word.at(word.size()-1) << " from word " << word << endl;
			word->erase(separador);
		}
		else
			return false;
	}	
	
	if (word->size() == 0 )
		return false;
	
	return true;
}

string IndexParser::ToLower(const string* word)
{
	string s = "";
	char* aux = const_cast<char *>(word->c_str());
	for(size_t i = 0; i < word->size(); i++)
		s += tolower(aux[i]);
	return s;
}

